using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Xml;
using System.IO;

namespace Safira.Tools.Sharepoint.Spome
{
    public class ESPList
    {
        SPList myList;
        bool silentMode = true;

        /// <summary>
        /// Gets or sets my list.
        /// </summary>
        /// <value>My list.</value>
        public SPList MyList
        {
            get { return myList; }
            set { myList = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ESPList"/> class.
        /// </summary>
        /// <param name="currWeb">The curr web.</param>
        /// <param name="nodeXml">The node XML.</param>
        public ESPList(SPWeb currWeb, XmlReader nodeXml)
        {
            if ( ! currWeb.Exists ) 
            {
                throw new ArgumentException( "currWeb doesnt exist" );
            }
                
            if ( nodeXml == null )
            {
                throw new ArgumentNullException( "nodeXml is null" );
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ESPList"/> class.
        /// </summary>
        /// <param name="list">The list.</param>
        public ESPList(SPList list)
        {
            myList = list;
        }

        /// <summary>
        /// Gets the applied content types.
        /// </summary>
        /// <returns></returns>
        public string[] GetAppliedContentTypes()
        {
            string[] ret = new string[myList.ContentTypes.Count];
            int i = 0;
            foreach (SPContentType spct in myList.ContentTypes)
            {
                ret[ i ] = spct.Name;
                i++;
            }
            return ret;
        }

        /// <summary>
        /// Adds the type of the content.
        /// </summary>
        /// <param name="spCType">Type of the sp C.</param>
        public void AddContentType(SPContentType spCType)
        {
            if (myList.ContentTypes[spCType.Name] == null)
            {
                myList.ContentTypes.Add(spCType);
                myList.Update();
                Console.WriteLine(String.Format("\tAdded ContentType {0}",spCType.Name) );
            }
        }

        /// <summary>
        /// Approves the list.
        /// </summary>
        public void ApproveList()
        {
            Console.WriteLine("Approving List {0}...", myList.Title);

            foreach (SPListItem myItem in myList.Items)
            {
                try
                {
                    myItem.ModerationInformation.Status = SPModerationStatusType.Approved;
                    myItem.Update();
                }
                catch (Exception e)
                {
                    if (!silentMode)
                    {
                        Console.WriteLine("Could Not aprove {0}", myItem.DisplayName);
                        Console.WriteLine(e.Message);
                    }
                }
            }
            myList.Update();

            Console.WriteLine("DONE");
        }

        /// <summary>
        /// Uploads the files.
        /// </summary>
        /// <param name="folderName">Name of the folder.</param>
        /// <returns></returns>
        public bool UploadFiles( string folderName, string filter )
        {
            string[] fileEntries = Directory.GetFiles( folderName );

            foreach ( string fileName in fileEntries )
            {
                string spFileName = fileName.Substring( fileName.LastIndexOf( "\\" ) + 1 );
                bool run = true;

                #region filters

                if ( filter != null )
                {
                    if ( !spFileName.EndsWith( filter ) )
                        run = false;
                }

                #endregion

                if ( run )
                {
                    SPFile myFile = FindSPFile( spFileName );

                    if ( myFile != null )
                    {
                        using ( FileStream fs = new FileStream( fileName, FileMode.Open ) )
                        {
                            using ( BinaryReader br = new BinaryReader( fs ) )
                            {
                                try
                                {
                                    #region Upload Content

                                    byte[] bytes = br.ReadBytes( (int) br.BaseStream.Length );
                                    
                                    myFile.CheckOut();
                                    myFile.SaveBinary( bytes );
                                    myFile.CheckIn( "Uploaded by SPOME" );
                                   
                                    if (myList.EnableVersioning && myList.EnableMinorVersions)
                                    {
                                        myFile.Publish( "Published by SPOME" );
                                        myFile.Approve( "Approved by SPOME" );
                                    }
                                    
                                    #endregion
                                }
                                finally
                                {
                                    #region Closing streams

                                    if ( fs != null )
                                        fs.Close();

                                    if ( br != null )
                                        br.Close();
                                    #endregion
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// Uploads the files.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="filename">The filename.</param>
        /// <returns></returns>
        public bool UploadFile( byte[] content, string filename)
        {
            SPFile myFile = FindSPFile( filename );

            if ( myFile != null )
            {
                try
                {
                    #region Upload Content

                    myFile.CheckOut();
                    myFile.SaveBinary( content );
                    myFile.CheckIn( "Uploaded by SPOME" );
                   
                    if (myList.EnableVersioning && myList.EnableMinorVersions)
                    {
                        myFile.Publish( "Published by SPOME" );
                        myFile.Approve( "Approved by SPOME" );
                    }
                    
                    #endregion
                }
                catch
                {}
                return true;
            }
            return false;
        }

        /// <summary>
        /// Downloads the files.
        /// </summary>
        /// <param name="folderName">Name of the folder.</param>
        /// <returns></returns>
        public bool DownloadFiles( string folderName, string filter )
        {
            DirectoryInfo dir = Directory.CreateDirectory( folderName );

            foreach ( SPListItem myItem in myList.Items )
            {
                SPFile myFile = myItem.File;
                Encoding myEncoding = Encoding.UTF8;

                bool run = true;

                #region filters

                if ( filter != null )
                {
                    if ( !myFile.Name.EndsWith( filter ) )
                        run = false;
                }

                #endregion

                if ( run )
                {
                    using ( FileStream fs = new FileStream( folderName + myFile.Name, FileMode.OpenOrCreate ) )
                    {
                        using ( BinaryWriter br = new BinaryWriter( fs ) )
                        {
                            try
                            {
                                byte[] content = myFile.OpenBinary();

                                br.Write( content );
                            }
                            finally
                            {
                                br.Close();
                            }
                        }
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// Finds the SP file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        private SPFile FindSPFile( string fileName )
        {
            foreach ( SPListItem myItem in myList.Items )
            {
                SPFile myFile = myItem.File;
                
                if ( myFile.Name.Equals( fileName ) )
                    return myFile;
            }

            return null;
        }

        
    }
}
